package com.sfac.springBoot.modules.account.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sfac.springBoot.modules.account.dao.UserDao;
import com.sfac.springBoot.modules.account.dao.UserRoleDao;
import com.sfac.springBoot.modules.account.entity.User;
import com.sfac.springBoot.modules.account.entity.UserRole;
import com.sfac.springBoot.modules.account.service.UserService;
import com.sfac.springBoot.modules.common.vo.Result;
import com.sfac.springBoot.modules.common.vo.Search;
import com.sfac.springBoot.modules.test.entity.City;
import com.sfac.springBoot.utils.MD5Util;
import com.sfac.springBoot.utils.RedisUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {
    public final static Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RedisUtils redisUtils;
    @Override
    public Result<User> login(User user) {
//        User login = userDao.login(user.getUserName());
//        if (login==null){
//            return new Result<>(Result.ResultStatus.ERROR.code,"账号错误");
//        }
//        else if(!login.getPassword().equals(MD5Util.getMD5(user.getPassword()))){
//            return new Result<>(Result.ResultStatus.ERROR.code,"密码错误");
//        }
        int maxError=3;
        String errorKey = String.format("login_error_count_%s", user.getUserName());
        // 错误次数
        int errorCount = redisUtils.get(errorKey)  == null ? 0 : (Integer) redisUtils.get(errorKey);
        if (errorCount >= maxError) {
            return new Result<>(Result.ResultStatus.ERROR.code,
                    String.format("用户连续错误登录三次，锁定账户 30 秒。"));
        }
        Subject subject= SecurityUtils.getSubject();
        UsernamePasswordToken token=
                new UsernamePasswordToken(user.getUserName(),MD5Util.getMD5(user.getPassword()));
        User temp=null;
        try {
            subject.login(token);
            subject.checkRoles();
            temp= (User) subject.getPrincipal();
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.debug(e.getMessage());
            redisUtils.increment(errorKey, 1);
            errorCount = redisUtils.get(errorKey)  == null ? 0 : (Integer) redisUtils.get(errorKey);
            if (errorCount >= maxError) {
                redisUtils.expire(errorKey, 30);
                return new Result<>(Result.ResultStatus.ERROR.code,
                        String.format("用户连续登录错误 %d 次，锁住账户 30 秒。", errorCount));
            } else  {
                return new Result<>(Result.ResultStatus.ERROR.code,
                        String.format("用户连续登录错误 %d 次，还剩 %d 次机会。", errorCount, (maxError - errorCount)));
            }
        }
        return new Result<>(Result.ResultStatus.SUCCESS.code,"success",temp);
    }

    @Override
    public Result<User> update(User user) {
        User login = userDao.login(user.getUserName());
        if (login!=null){
            return new Result<>(Result.ResultStatus.ERROR.code,"账号已存在");
        }
        userDao.updateUser(user);
        return new Result<>(Result.ResultStatus.SUCCESS.code,"修改成功");
    }

    @Override
    public User getUserById(int id) {
        return  userDao.getUserById(id);
    }

    @Override
    public User getUserByName(String userName) {
        return userDao.login(userName);
    }

    @Override
    public Result<User> deleteUserById(int id) {
        userDao.deleteUser(id);
        return new Result<>(Result.ResultStatus.SUCCESS.code,"删除成功");
    }

    @Override
    public Result<User> register(User user) {
        User login = userDao.login(user.getUserName());
        if (login!=null){
            return new Result<>(Result.ResultStatus.ERROR.code,"账号已存在");
        }
        user.setCreateDate(LocalDateTime.now());
        user.setPassword(MD5Util.getMD5(user.getPassword()));
        userDao.insertUser(user);
        if (user.getRoles() != null && user.getRoles().size() > 0) {
            user.getRoles().stream().forEach(item -> {
                userRoleDao.insertUserRole(new UserRole(user.getId(), item.getId()));
            });
        }
        return new Result<>(Result.ResultStatus.SUCCESS.code,"注册成功");
    }

    @Override
    public PageInfo<User> loadAllUsers(Search search) {
        search.init();
        PageHelper.startPage(search.getCurrentPage(),search.getPageSize());
        return new PageInfo<User>(Optional.ofNullable(userDao.loadAllUsers(search)).orElse(Collections.emptyList()));
    }
}
